package com.zm.openapi.lb;

import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.Server;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.List;

/**
 * @description:
 * @module: com.zm.apigateway.loadbalance
 * @author: songxiongli
 * @date: 2020-08-11 19:35
 **/
@Slf4j
public class TokenHashBalanceRule extends AbstractLoadBalancerRule {

    @Override
    public void initWithNiwsConfig(IClientConfig iClientConfig) {
    }

    @Override
    public Server choose(Object o) {
        List<Server> servers = this.getLoadBalancer().getReachableServers();
        if (servers.isEmpty()) {
            return null;
        }
        if (servers.size() == 1) {
            return servers.get(0);
        }
        if (StringUtils.isBlank((String) o)) {
            return randomChoose(servers);
        }
        return hashTokenChoose(servers, (String) o);
    }

    private Server randomChoose(List<Server> servers) {
        int randomIndex = RandomUtils.nextInt(0, servers.size());
        return servers.get(randomIndex);
    }

    private Server hashTokenChoose(List<Server> servers, String token) {
        int hashcode = Math.abs(token.hashCode());
        log.info("token hash 负责均衡策略： servers={} ,token={},hashcode={}", servers, token, hashcode);
        return servers.get(hashcode % servers.size());
    }
}
